package com.ciccwm.auth.util;

import com.ciccwm.auth.config.properties.AuthProperties;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;

/**
 * JWT工具类.
 */
@Component
@RequiredArgsConstructor
public class JwtTokenUtil {
    private static final long MILLISECONDS_IN_SECOND = 1000L;
    private final AuthProperties authProperties;

    /**
     * 获取密钥.
     *
     * @return 密钥
     */
    private SecretKey getSigningKey() {
        return Keys.hmacShaKeyFor(authProperties.getJwt().getSecret().getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 生成JWT令牌.
     *
     * @param subject 令牌主题
     * @param expirationSeconds 过期时间（秒）
     * @return JWT令牌字符串
     */
    public String generateToken(String subject, long expirationSeconds) {
        return Jwts.builder()
                .subject(subject)
                .issuedAt(new Date())
                .expiration(new Date(System.currentTimeMillis() + expirationSeconds * MILLISECONDS_IN_SECOND))
                .signWith(getSigningKey())
                .compact();
    }

    /**
     * 从令牌中获取主题.
     *
     * @param token JWT令牌
     * @return 令牌主题
     */
    public String getSubjectFromToken(String token) {
        Claims claims = Jwts.parser()
                .verifyWith(getSigningKey())
                .build()
                .parseSignedClaims(token)
                .getPayload();
        return claims.getSubject();
    }

    /**
     * 验证令牌是否有效.
     *
     * @param token JWT令牌
     * @return 如果令牌有效则返回true，否则返回false
     */
    public boolean validateToken(String token) {
        try {
            Jwts.parser()
                    .verifyWith(getSigningKey())
                    .build()
                    .parseSignedClaims(token);
            return true;
        } catch (ExpiredJwtException e) {
            return false;
        } catch (Exception e) {
            return false;
        }
    }
} 
